package com.cmsz.paydemo.util;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;

public class SignUtil {
	
	public static void main(String[] args) throws Exception {
		String origin = "<Header></Header><Body>abc</Body><CerID></CerID><SignValue></SignValue>";
		String origin2 = sign(origin);
		System.out.println(origin2);
		boolean verifyFlag = checkSign(origin2);
		System.out.println(verifyFlag);
	}
	
	public static String sign(String origin) throws Exception {
		KeyStore ks = KeyStore.getInstance("JKS");
		FileInputStream fis = new FileInputStream("myKeystore.keystore");
		ks.load(fis, ConfigUtil.getProperty("ksyStorePwd").toCharArray());
		PrivateKey privateKey = (PrivateKey) ks.getKey(ConfigUtil.getProperty("alias"), ConfigUtil.getProperty("password").toCharArray());
		X509Certificate cert = (X509Certificate) ks.getCertificate("myCertificate");
		String cerId = cert.getSerialNumber().toString(16).toUpperCase();
		byte[] data = getMainString(origin).getBytes("UTF-8");
		Signature signature = Signature.getInstance("SHA1withRSA");
		signature.initSign(privateKey);
		signature.update(data);
		byte[] b = signature.sign();
		String signValue = new String(Base64.getEncoder().encode(b));
		String temp = XmlUtils.relaceNodeContent("<CerID>", "</CerID>", cerId, origin);
		String result = XmlUtils.relaceNodeContent("<SignValue>", "</SignValue>", signValue, temp);
		return result;
	}
	
	public static boolean checkSign(String origin) throws Exception {
		CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
		X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream("myCer.cer"));
		PublicKey publicKey = certificate.getPublicKey();
		String cerId = certificate.getSerialNumber().toString(16).toUpperCase();
		byte[] data = getMainString(origin).getBytes("UTF-8");
		Signature sign = Signature.getInstance("SHA1withRSA");
		sign.initVerify(publicKey);
		sign.update(data);
		String signature = XmlUtils.parseNodeValueFromXml("<SignValue>", "</SignValue>", origin);
		byte[] b = Base64.getDecoder().decode(signature);
		return sign.verify(b);
	}
	
	private static String getMainString(String origin) {
		int headerIndex = origin.indexOf("<Header>");
		int headerLast = origin.indexOf("</Header>");
		String headers = origin.substring(headerIndex, headerLast + "</Header>".length());
		String body = XmlUtils.parseNodeValueFromXml("<Body>", "</Body>",
				origin);
		StringBuffer sb = new StringBuffer();
		sb.append(headers).append("|").append("<Body>" + body + "</Body>");
		return sb.toString();
	}

}
